import { useEffect, useRef, useState } from 'react';

/**
 * 延迟加载图片的函数
 *
 * @param src 图片的URL地址
 * @returns 返回一个包含imgRef引用和根据isLoaded状态动态改变的src字符串的数组
 */
const useLazyImage = (src: string): [React.RefObject<HTMLImageElement>, string] => {
    // 使用React的useState钩子创建一个状态变量isLoaded，初始值为false
    const [isLoaded, setIsLoaded] = useState(false);
    // 使用React的useRef钩子创建一个引用imgRef，初始值为null
    const imgRef = useRef<HTMLImageElement>(null);

    useEffect(() => {
        const node = imgRef.current;
        if (!node) return;

        // 创建一个IntersectionObserver实例，用于观察目标元素是否进入视口
        const observer = new IntersectionObserver(
            (entries, observer) => {
                // 仅关心第一个 entry（因为我们只 observe 单个 node）
                const entry = entries[0];
                // 如果元素进入视口
                if (entry && entry.isIntersecting) {
                    // 设置isLoaded状态为true
                    setIsLoaded(true);
                    // 停止观察该目标（如果以后还会观察其它目标可保留 observer）
                    try {
                        observer.unobserve(entry.target);
                    } catch {
                        // ignore
                    }
                }
            },
            // 设置观察阈值为0.1，即当目标元素的10%进入视口时触发回调函数
            { threshold: 0.1 }
        );

        observer.observe(node);

        // 返回一个清理函数，在组件卸载时执行
        return () => {
            // 组件卸载时彻底断开 observer，释放资源
            try {
                observer.unobserve(node);
            } catch {
                // ignore
            }
            try {
                observer.disconnect();
            } catch {
                // ignore
            }
        };
    }, [imgRef.current]);

    // 返回imgRef引用和根据isLoaded状态动态改变的src字符串
    return [imgRef, isLoaded ? src : ''];
};

export default useLazyImage;
